package server

import (
	"encoding/json"
	"fmt"
	"httpserver/config"
	"io"
	"net/http"
	"os"

	"github.com/sirupsen/logrus"
)

func writeToClient(w http.ResponseWriter, r *http.Request, statusCode int, content []byte) {
	// logrus.Infof("recv %s request, method:%s, uri:%s", r.RemoteAddr, r.Method, r.RequestURI)
	logrus.WithField("client", r.RemoteAddr).WithField("method", r.Method).WithField("uri",r.RequestURI).Info("revc request")
	w.WriteHeader(statusCode)
	if _, err := w.Write(content); err != nil {
		logrus.Warnf("write to %s failed,err:%s", r.RequestURI, err.Error())
		return
	}
	logrus.Debugf("write to %s succeed,status:%d,content:%s", r.RemoteAddr, statusCode, content)
}

func serverIndex(w http.ResponseWriter, r *http.Request) {
	f, err := os.Open("html/index.html")
	if err == nil {
		content, _ := io.ReadAll(f)
		writeToClient(w, r, http.StatusOK, content)
	} else {
		if ! os.IsExist(err) {
			writeToClient(w, r, http.StatusNotFound, []byte("Not Found"))
		} else {
			writeToClient(w, r, http.StatusInternalServerError, []byte("Unknow Error"))
		}
	}
}

func queryStudents(w http.ResponseWriter, r *http.Request) {
	var stdudents = make([]*Student, 0, 20)
	err := DB.Model(&Student{}).Limit(20).Find(&stdudents).Error
	if err != nil {
		logrus.Errorf("query students failed,err:%s", err.Error())
		writeToClient(w, r, http.StatusInternalServerError, []byte("Query failed"))
		return
	}
	v, err := json.Marshal(stdudents)
	if err != nil {
		logrus.Errorf("json marshal students failed,students:%+v,err:%s", stdudents, err.Error())
		writeToClient(w, r, http.StatusInternalServerError, []byte("Query failed"))
		return
	}
	writeToClient(w, r, http.StatusOK, v)
}

func Run() {
	http.HandleFunc("/", serverIndex)
	http.HandleFunc("/students", queryStudents)
	if err := http.ListenAndServe(fmt.Sprintf("%s:%d", config.GlobalConfig.ListenAddress, config.GlobalConfig.ListenPort), nil); err != nil {
		logrus.Fatal(err)
	}
}
